<template>
  <el-dialog
    v-if="type === 'dialog'"
    v-bind="$attrs"
    v-model="visiable"
    :title="title"
    draggable
    @closed="handleClosed"
  >
    <template v-for="item in renderChildren" #[item.name] :key="item.name">
      <component :is="item.component" :key="item.name" />
    </template>
  </el-dialog>
  <el-drawer
    v-else-if="type === 'drawer'"
    v-model="visiable"
    v-bind="$attrs"
    :title="title"
    draggable
    @closed="handleClosed"
  >
    <template v-for="item in renderChildren" #[item.name] :key="item.name">
      <component :is="item.component" :key="item.name" />
    </template>
  </el-drawer>
  <div v-else class="inner-page" :style="{ zIndex: (props.zindex || 1) + 10 }">
    <Transition name="innerPage" mode="out-in" @after-leave="handleClosed">
      <div v-if="visiable" class="inner-container">
        <div class="inner-header">
          <div class="back-btn" @click="close()">
            <el-icon size="24"><ArrowLeft /></el-icon>
          </div>
          <slot name="header">
            <span calss="title"> {{ title }}</span>
          </slot>
        </div>
        <div class="inner-body">
          <el-scrollbar>
            <slot></slot>
          </el-scrollbar>
        </div>
      </div>
    </Transition>
  </div>
</template>

<script lang="ts" setup name="FloatComponents">
  import { computed, ref, useSlots } from 'vue';
  import { ElDialog, ElDrawer } from 'element-plus';
  import { ArrowLeft } from '@element-plus/icons-vue';
  const props = defineProps<{
    type: 'dialog' | 'drawer' | 'page';
    title?: string;
    zindex?: number;
  }>();

  const solts = useSlots();

  const emits = defineEmits(['closed']);

  const visiable = ref(false);

  const closeHandleEvent = ref<any>(undefined);

  const renderChildren = computed(() =>
    Object.entries(solts).map(([name, component]) => ({
      name,
      component
    }))
  );
  const handleClosed = () => {
    emits('closed', closeHandleEvent.value);
    closeHandleEvent.value = undefined;
  };
  const close = (closeHandle?: () => void) => {
    visiable.value = false;
    closeHandleEvent.value = closeHandle;
  };

  const open = () => {
    visiable.value = true;
  };

  defineExpose({
    open,
    close
  });
</script>

<style lang="less" scoped>
  .inner-page {
    position: absolute;
    top: 1px;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--el-bg-color-page);
    .inner-container {
      margin: 15px;
      height: calc(100% - 30px);
      background-color: var(--el-bg-color);
      display: flex;
      flex-direction: column;
      .inner-header {
        border-bottom: 1px solid var(--el-border-color);
        font-size: 18px;
        display: flex;
        flex-direction: row;
        align-items: center;
        font-weight: bold;
        padding: 15px;
        .back-btn {
          cursor: pointer;
          display: flex;
          flex-direction: row;
          align-items: center;
          margin-right: 8px;
        }
      }
      .inner-body {
        flex: 1;
        overflow: hidden;
      }
    }
  }
</style>
